<template>
  <div class='chatRoom'>
    <main>
      <el-page-header @back='goBack' content='正大光明聊天室' />
      <div class='chatBox'>
        <!-- 系统消息区 -->
        <el-card class='box-card card1'>
          <div class='system-message'>
            系统消息：{{ sysMsg }}
          </div>
        </el-card>
        <!-- 聊天区 -->
        <el-card class='box-card card2'>
          <!-- 聊天记录区 -->
          <div class='chatArea' ref='chatArea'>
            <div class='chatListArea' ref='chatListArea'>
              <div class='chatList' v-for='(item,index) in msgList' :key='index'>
                <div class='msgList' v-if='!item.isSelf'>
                  <el-row :gutter='10' style='display: flex;align-items: center;'>
                    <el-col :span='1'>
                      <el-avatar :src='item.avatar' />
                    </el-col>
                    <el-col :span='20'>
                      <strong>{{ item.userName }}</strong>
                    </el-col>
                  </el-row>
                  <el-row :gutter='10'>
                    <el-col :span='20' :offset='1'>
                      <el-card class='content'>
                        <p v-if='item.content.msg'>
                          <span>{{ item.content.msg }}</span>
                        </p>
                        <p v-if='item.content.img'>
                          <el-image
                            @load='showNewMsg'
                            style='width: 300px;'
                            :src='item.content.img'
                            :preview-src-list='item.content.srcList'>
                            <i slot='placeholder' class='el-icon-picture-outline' />
                          </el-image>
                        </p>
                      </el-card>
                    </el-col>
                  </el-row>
                </div>
                <div class='msgList self' v-else>
                  <el-row :gutter='10' style='display: flex;align-items: center;'>
                    <el-col :span='20' :offset='3' style='display: flex;justify-content: end'>
                      <strong>{{ item.userName }}</strong>
                    </el-col>
                    <el-col :span='0.5'>
                      <el-avatar :src='item.avatar' />
                    </el-col>
                  </el-row>
                  <el-row :gutter='10'>
                    <el-col :span='20' :offset='3' style='display: flex;justify-content: end'>
                      <el-card class='content'>
                        <p v-if='item.content.msg'>
                          <span>{{ item.content.msg }}</span>
                        </p>
                        <p v-if='item.content.img'>
                          <el-image
                            @load='showNewMsg'
                            style='width: 300px;'
                            :src='item.content.img'
                            :preview-src-list='item.content.srcList'>
                            <i slot='placeholder' class='el-icon-picture-outline' />
                          </el-image>
                        </p>
                      </el-card>
                    </el-col>
                  </el-row>
                </div>
              </div>
            </div>
          </div>
          <!-- 发言区 -->
          <div class='send'>
            <el-row :gutter='10'>
              <el-col :span='1'>
                <input ref='chatImg' @change='sendImg' style='display: none;' type='file' name='chatImg' id='chatImg' />
                <label for='chatImg'>
                  <span class='el-icon-picture-outline' />
                </label>
              </el-col>
              <el-col :span='1'>
                <span class='el-icon-select' @click.stop='showEmoji = true'>😀</span>
              </el-col>
            </el-row>
            <!-- 单独装一个 div 阻止事件冒泡 -->
            <div @click.stop>
              <VEmojiPicker
                v-if='showEmoji'
                :dark='true'
                :showSearch='false'
                class='v-emoji'
                @select='selectEmoji'
              />
            </div>

            <el-row :gutter='10'>
              <el-col :span='24'>
                <el-input
                  maxlength='300'
                  resize='none'
                  rows='3'
                  class='editMsg'
                  v-model='msg'
                  type='textarea' placeholder='请文明发言...'
                  @keyup.enter.native='sendMessage'
                />
              </el-col>
            </el-row>

            <el-row :gutter='10' style='display: flex;align-items:center;margin-top: 5px;'>
              <el-col :span='1' :offset='21'>
                <span>{{ msg.length }}/300 </span>
              </el-col>
              <el-col :span='2'>
                <el-button
                  class='sendBtn'
                  type='primary'
                  size='small'
                  @click='sendMessage'
                >
                  发送
                  <i class='el-icon-s-promotion el-icon--right' />
                </el-button>
              </el-col>
            </el-row>
          </div>
        </el-card>
      </div>
    </main>
  </div>
</template>

<script>

import { VEmojiPicker } from 'v-emoji-picker-custom'
import { io } from 'socket.io-client'
import pageUrl from '@/config/pageUrl'

export default {
  name: 'ChatHome',
  components: {
    VEmojiPicker
  },
  mounted() {
    // 初始化 socket
    this.createSocket()
    // 点击其他地方让表情组件消失
    document.addEventListener('click', () => this.showEmoji = false)
  },
  watch: {
    msgList: {
      handler() {
        // 有消息更新 展示最新的一条消息
        this.$nextTick(() => {
          this.showNewMsg()
        })
      },
      immediate: true
    }
  },
  beforeDestroy() {
    this.socket.disconnect()
  },
  data() {
    return {
      sysMsg: '',
      img: '',
      msg: '',
      socket: null,
      showEmoji: false,
      userData: JSON.parse(sessionStorage.getItem('userData')),
      msgList: []
    }
  },
  methods: {
    goBack() {
      this.socket.emit('leave', { socket_id: this.socket.id, userName: this.userData.userName })
      this.$router.go(-1)
    },
    createSocket() {
      this.socket = io(pageUrl.chatHome, {
        transports: ['websocket']
      })
      this.socket.on('connect', () => {
        this.$message.success('加入聊天室成功！本站不会保存当前聊天记录！')
        this.socket.emit(
          'enter',
          { socket_id: this.socket.id, userName: this.userData.userName })
      })
      this.socket.on('msg', data => {
        this.sysMsg = data.msg
      })
      this.socket.on('newMsg', data => {
        data.isSelf = data.userId === this.userData.userId
        this.msgList.push(data)
      })
    },
    showNewMsg() {
      const list = this.$refs.chatListArea
      const area = this.$refs.chatArea
      if(getComputedStyle(list).height >= getComputedStyle(area).height){
        list.style.height = '100%'
        list.onmouseenter = () => {
          list.style.overflowY = 'scroll'
        }
        list.onmouseleave = () => {
          list.style.overflowY = 'hidden'
        }
        list.scrollTop = list.scrollHeight
      }
    },
    selectEmoji(emoji) {
      this.msg += emoji.data
    },
    sendMessage() {
      if (!this.img && !this.msg) {
        return this.$message.warning('请不要发送空消息！')
      }
      let data = {
        userName: this.userData.userName,
        avatar: this.userData.avatar,
        userId: this.userData.userId,
        isSelf: true,
        socket_id: this.socket.id,
        content: {
          msg: this.msg,
          img: this.img,
          srcList: [this.img]
        }
      }
      this.socket.emit('sendMsg', data)
      this.msg = ''
      this.img = ''
    },
    sendImg() {
      this.uploadImg().then(url => {
        this.img = url
        this.sendMessage()
      }).catch(err => this.$message.error(err))
    },
    uploadImg() {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        // 转码为 base64
        reader.readAsDataURL(this.$refs.chatImg.files[0])
        // 清空文件选择 允许再次选择同一张图片
        this.$refs.chatImg.value = ''
        reader.onload = () => {
          if (this.showSize(reader.result) > 3) {
            reject('图片尺寸请控制在3M以内！')
          } else {
            resolve(reader.result)
          }
        }
      })
    },
    // 计算 base64 圖片尺寸 返回 单位 M
    showSize(base64url) {
      const strLength = base64url.length
      // 计算后得到的文件流大小，单位为字节
      const fileLength = parseInt(strLength - (strLength * 2 / 8))
      // 由字节转换为 M
      const size = (fileLength / 1024 / 1024).toFixed(2)
      return size
    }
  }
}
</script>

<style scoped>
div.chatRoom {
  display: flex;
  justify-content: center;
  width: 100vw;
  height: 100vh;
  background-color: rgb(40, 44, 52);
}

div.chatRoom main {
  overflow: hidden;
  width: 70%;
  height: 100%;
  background-color: rgb(52, 58, 70);
  opacity: 0.8;
}

>>> .el-page-header__left .el-icon-back {
  color: wheat;
  font-size: 24px;
}

>>> .el-page-header__title {
  font-size: 20px;
  color: wheat;
}

>>> .el-page-header__left::after {
  width: 2px;
  background-color: wheat;
}

>>> .el-page-header__content {
  color: wheat;
}

div.chatBox {
  width: 98%;
  height: 100%;
  margin: 0 auto;
}

.box-card {
  margin-top: 20px;
  color: #cccccc;
  background-color: rgb(52, 58, 70);
  border-color: rgb(76, 84, 101);
}

.card1 {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 6%;
}

.card2 {
  height: 84%;
}

div.system-message {
  text-align: center;
}

div.chatArea {
  height: 62vh;
}

div.chatListArea {
  overflow: hidden;
  width: 100%;
  padding: 0 5px;
}

/*div.chatListArea:hover {*/
/*  overflow-y: scroll;*/
/*}*/

div.chatListArea::-webkit-scrollbar {
  width: 2px;
}

div.chatListArea::-webkit-scrollbar-thumb {
  box-shadow: 0 0 3px rgba(238, 232, 232, 0.96) inset;
  border-radius: 10px;
}

div.chatListArea::-webkit-scrollbar-track {
  background-color: rgba(37, 47, 72, 0.3);
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.5) inset;
  border-radius: 10px;
}

div.msgList {
  overflow: hidden;
  margin-bottom: 10px;
}

p {
  margin: 0;
  padding: 0;
}

div.content {
  display: inline-block;
  padding: 0;
  background-color: rgb(52, 58, 70);
  border-color: rgb(76, 84, 101);
}

>>> div.content .el-card__body {
  padding: 10px;
}

div.content p:nth-of-type(1) {
  padding: 4px 0;
}

div.content p span {
  line-height: 1.5;
  color: white;
}

div.send {
  position: relative;
  border-top: 2px solid #3a4965;
}

>>> #Emojis {
  visibility: hidden;
  height: 0;
  transition: height .5s;
}

.v-emoji {
  position: absolute;
  left: 4%;
  bottom: 104%;
}

>>> .v-emoji:hover > #Emojis {
  visibility: visible;
  height: 200px;
}

span.el-icon-picture-outline, span.el-icon-select {
  display: block;
  width: 100%;
  height: 100%;
  font-size: 40px;
  cursor: pointer;
  text-align: center;
  transition: color .3s;
}

span.el-icon-select {
  line-height: 1.1;
  font-size: 34px;
  border-radius: 50%;
}

span.el-icon-select:hover {
  font-size: 36px;
}

span.el-icon-picture-outline:hover {
  transition: color .2s;
  color: #409EFF;
}

>>> .editMsg textarea {
  padding: 4px;
  font-size: 16px;
  background: none;
  border: none;
  color: #fff;
}

>>> .editMsg textarea::-webkit-scrollbar {
  width: 4px;
}

>>> .editMsg textarea::-webkit-scrollbar-thumb {
  box-shadow: 0 0 3px rgba(238, 232, 232, 0.96) inset;
  border-radius: 10px;
}

>>> .editMsg textarea::-webkit-scrollbar-track {
  background-color: rgba(37, 47, 72, 0.3);
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.5) inset;
  border-radius: 10px;
}

.sendBtn {
  font-size: 14px;
  background: none;
  border: 2px solid #3a4965;
}

.sendBtn:hover {
  border: 2px solid #425881;
  color: wheat;
  box-shadow: 0 0 3px wheat;
}

.sendBtn:active {
  background: #425881;
}


</style>
